home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr40 / x1j4_src.zip / TNL7B2.C < prev    next >
Text File  |  1995-02-12  |  29KB  |  1,139 lines

  1. /*****************************************************************************/
  2. /*                                              */
  3. /*                                         */
  4. /*    *****              *****                      */
  5. /*     *****            *****                         */
  6. /*       *****          *****                         */
  7. /*         *****        *****                         */
  8. /*  ***************      ***************                     */
  9. /*  *****************    *****************                     */
  10. /*  ***************      ***************                     */
  11. /*         *****        *****       TheNet                    */
  12. /*       *****          *****       Portable. Compatible.         */
  13. /*     *****            *****       Public Domain             */
  14. /*    *****              *****    NORD><LINK                  */
  15. /*                                         */
  16. /* This software is public domain ONLY for non commercial use                */
  17. /*                                                                           */
  18. /*                                         */
  19. /*****************************************************************************/
  20.  
  21. /* Level 7B, Befehlsinterpreter, Befehle                     */
  22. /* Version 1.01                                   */
  23. /* Hans Georg Giese, DF2AU, Hinter dem Berge 5, 3300 Braunschweig         */
  24. /* 08-MAY-88                                     */
  25.  
  26. /* Modified by G8KBB - Jan 91                              */
  27. /*      - Use of register keyword for code reduction                         */
  28. /*      - Use all.h header file                                              */
  29. /*      - add command 'stats' conditionally on definition of STATSCMD        */
  30. /*      - add host command optionally on HOSTCMD definition                  */
  31. /*      - add 'bbs' command optionally on HOSTCMD                            */
  32. /*      - add 'mheard' support                                               */
  33. /*      - conditionally, include MODE command and reuse common code in PARAM */
  34. /*      - add TALK command optionally on TALKCMD                             */
  35. /*      - add LINKS command optionally on LINKSCMD                           */
  36. /*      - add calibrate command optionally on CWID                           */
  37. /*      - add DXcluster command optionally on DXCLUSTER if HOSTCMD defined   */
  38. /*      - add hostalias, bbsalias, dxcalias & alias commands                 */
  39. /*      - add bye and quit commands                                          */
  40. /*      - add manager and associated audit command                           */
  41. /*      - add closedown command                                              */
  42. /*      - add help command                                                   */
  43. /*      - add btext and ctext commands & make them & info multi line         */
  44. /*      - add calibrate command if cwid is loaded to permit calibration of tx*/
  45. /*      - add UI command to permit arbitrary UI frames to be sent            */
  46. /*      - add acl command and associated subsystems to manage acls           */
  47.  
  48. /* This half of the command interpreter commands contains the following :
  49.  *       STATS        HOST           HOSTALIAS       BBS        BBSALIAS
  50.  *       DXCLUSTER    DXCALIAS       BYE/QUIT        MHEARD     TALK
  51.  *       LINKS        MANAGER        CLOSEDOWN       HELP       BTEXT
  52.  *       CTEXT        AUDIT          CALIBRATE       UI         ACL
  53.  */
  54.  
  55. /*
  56.  * September 1993 - released as TheNet X-1J
  57.  */
  58.  
  59. /* Added S meter support and adc command
  60.  * update ccpmh for texnet display
  61.  */
  62.  
  63. #include "all.h"
  64. #include "tntyp.h"        /* Definition der Typen                 */
  65. #include "tnl7be.h"        /* externe Definitionen                 */
  66.  
  67.  
  68. char undefined[] = "undefined";
  69. char local_host[] = "Local host";
  70. char is[] = " is ";
  71.  
  72. #ifdef STATSCMD
  73. /*---------------------------------------------------------------------------*/
  74. VOID    ccpsts()        /* Befehl STATS                     */
  75. {
  76.   register mhtyp *bufpoi;        /* Buffer fuer Meldung         */
  77.   register unsigned i;
  78.  
  79.   bufpoi = putals("Statistics");
  80.   pstats("\015L1 Tx % : ", txstat, NUM1STATS, bufpoi );
  81.   pstats("\015L1 DCD% : ", rxstat, NUM1STATS, bufpoi );
  82.   pstats("\015L1 RxOvr: ", L2RXOVR, NUMPORTS*2, bufpoi );
  83.   pstats("\015L1 TxUnd: ", L2TXUND, NUMPORTS*2, bufpoi );
  84.   pstats("\015L2 RxCRC: ", L2RXCRC, NUMPORTS*2, bufpoi );
  85.   pstats("\015L2 heard: ", L2HDCNT, NUMPORTS*2, bufpoi );
  86.   pstats("\015L2 recvd: ", L2RXCNT, NUMPORTS*2, bufpoi );
  87.   pstats("\015L2 sent : ", L2TXCNT, NUMPORTS*2, bufpoi );
  88.   pstats("\015L2 RxRNR: ", L2RXRNR, NUMPORTS*2, bufpoi );
  89.   pstats("\015L2 RxREJ: ", L2RXREJ, NUMPORTS*2, bufpoi );
  90.   pstats("\015L2 TxRNR: ", L2TXRNR, NUMPORTS*2, bufpoi );
  91.   pstats("\015L2 TxREJ: ", L2TXREJ, NUMPORTS*2, bufpoi );
  92.   pstats("\015L2 fails: ", L2FAILS, NUMPORTS*2, bufpoi );
  93.   pstats("\015L3 g'wyd: ", l3gwcnt, 2, bufpoi );
  94.   pstats("\015L4 recvd: ", L4RXCNT, 2, bufpoi );
  95.   pstats("\015L4 sent : ", L4TXCNT, 2, bufpoi );
  96.   pstats("\015Buffers : ", minbuf, NUM1STATS, bufpoi );
  97.   pstats("\015CPU loop: ", cpucnt, NUM1STATS, bufpoi );
  98. #ifdef MONITORCMD
  99.   putstr("\015Timers  : ", bufpoi );    /* print the internal timers */
  100.   putnum_and_space( uptime, bufpoi );        /* as the time since warmstart */
  101.   putnum( runtime, bufpoi );        /* then the total runtime since cold*/
  102. #endif
  103. #ifdef PORTFLUSH
  104.   pstats("\015L1 flush: ", flushed, NUMPORTS, bufpoi );
  105. #endif
  106.   seteom(bufpoi);            /* Endekennung dran         */
  107. }
  108.  
  109. VOID pstats( string, values, count, bufpoi )
  110. char *string;
  111. register unsigned *values;
  112. register unsigned count;
  113. register mhtyp *bufpoi;
  114. {
  115.     putstr( string, bufpoi );
  116.     while( count-- )
  117.         putnum_and_space( *values++, bufpoi );
  118. }
  119.  
  120. VOID putnum_and_space( value, bufpoi )
  121. unsigned value;
  122. register mhtyp *bufpoi;
  123. {
  124.       putnum( value, bufpoi );    /* print minimum buffer values */
  125.       putchr( ' ', bufpoi );        /* followed by a space */
  126. }
  127.  
  128. #endif
  129.  
  130. #ifdef HOSTCMD
  131. /*---------------------------------------------------------------------------*/
  132. VOID ccphst()
  133. {
  134.   ccp_helper( hostid, &hidlen, ccpc13, 1 );
  135. }
  136.  
  137.  
  138. VOID ccphoa()
  139. {
  140.   ccp_alias_helper( hostalias, ccpc31 );
  141. }
  142.  
  143. VOID ccpbbs()
  144. {
  145.   ccp_helper( bbsid, &bbslen, ccpc15, 0 );
  146. }
  147.  
  148.  
  149. VOID ccpbba()
  150. {
  151.   ccp_alias_helper( bbsalias, ccpc29 );
  152. }
  153.  
  154. VOID ccpali()
  155. {
  156.   ccp_alias_helper( alias, ccpc33 );
  157. }
  158.  
  159. #ifdef DXCLUSTER
  160.  
  161. VOID ccpdxc()
  162. {
  163.   ccp_helper( dxcid, &dxclen, ccpc23, 0 );
  164. }
  165.  
  166. VOID ccpdxa()
  167. {
  168.   ccp_alias_helper( dxcalias, ccpc30 );
  169. }
  170.  
  171. #endif    /* DXCLUSTER */
  172.  
  173. /*---------------------------------------------------------------------------*/
  174. VOID ccp_helper( id, len, prompt, localflag )
  175. register char *id;
  176. register char *len;
  177. char *prompt;
  178. unsigned localflag;
  179. {
  180.   register mhtyp     *bufpoi;        /* Buffer fuer Meldung         */
  181.   
  182.   if( clicnt /* > 0 */ )
  183.   {
  184.       if (issyso() && *clipoi != '?' )    /* must be sysop & not asking*/
  185.         set_call( id, len );        /* in order to set the call  */
  186.       bufpoi = putals( prompt );
  187.       putstr( is, bufpoi );        /* Info mit Header         */
  188.       putstr( *id ? id : (localflag ? local_host : undefined ), bufpoi);
  189.       seteom(bufpoi);                /* Endekennung dran         */
  190.   }
  191.   else
  192.   {
  193.      if( *len > 0 )        /* if a host callsign has been set */
  194.      {
  195.          clipoi = id;    /* then fool connect into calling it */
  196.          clicnt = *len;
  197.          con_try_msg( id );
  198. #ifdef MODIFIED
  199.          ccp_con();
  200. #else
  201.          ccpcon();
  202. #endif
  203.      }
  204.      else if( localflag )
  205.      {
  206.          clicnt = 0;        /* otherwise connect to local host */
  207.          con_try_msg( local_host );
  208. #ifdef MODIFIED
  209.          ccp_con();
  210. #else
  211.          ccpcon();
  212. #endif
  213.      }
  214.      else
  215.      {
  216.          bufpoi = putals( "No " );
  217.          putstr( prompt, bufpoi );
  218.          putstr( " set", bufpoi );
  219.          seteom( bufpoi );
  220.      }
  221.   }
  222. }
  223.  
  224. /* helper utility to host and bbs commands that stores the callsign set
  225.  * by the sysop
  226.  * Accept up to 7 characters, and terminate if '*' is entered.
  227.  * '*' is used to clear the entry.
  228.  */
  229.  
  230. VOID set_call( string, size )
  231. register char *string;
  232. char *size;
  233. {
  234.     register unsigned chaptr;
  235.  
  236.     chaptr = 0;
  237.     while (clicnt != 0 && chaptr < 9 && *clipoi != '*' )
  238.     {
  239.         string[chaptr++] = *clipoi;
  240.         nxtcli();
  241.     }
  242.     string[chaptr] = 0;
  243.     *size = chaptr;
  244. }
  245.  
  246. VOID ccp_alias_helper( id, prompt )
  247. register char *id;
  248. char *prompt;
  249. {
  250.     register mhtyp     *bufpoi;        /* Buffer fuer Meldung         */
  251.     char tmpbuf[7];
  252.   
  253.     if (issyso() && *clipoi != '?' )    /* must be sysop & not asking*/
  254.     {
  255.         if( *clipoi == '*' )
  256.             cpy6ch( id, nulide );
  257.         else if( getide( tmpbuf ) > 0 )
  258.             cpy6ch( id, tmpbuf ); 
  259.     }
  260.     bufpoi = putals( prompt );
  261.     putstr( is, bufpoi );        /* Info mit Header         */
  262.     if( *id == ' ' )
  263.         putstr( undefined, bufpoi );
  264.     else
  265.         putcal( id, bufpoi );
  266.     seteom(bufpoi);                /* Endekennung dran         */
  267. }
  268.  
  269.  
  270. #endif /* HOSTCMD */
  271.  
  272. #ifdef MODIFIED
  273. /*---------------------------------------------------------------------------*/
  274. VOID ccpbye()
  275. {
  276.     if( hlpflg & 4 )
  277.         putmsg("Goodbye.");
  278.     disusr( userpo->cblk_u, userpo->typ_u );
  279.     kilusr();
  280. }
  281. #endif
  282.  
  283. /*---------------------------------------------------------------------------*/
  284.  
  285. #ifdef MONITORCMD
  286. #ifdef L3MONITOR
  287. VOID ccpmh()
  288. {
  289.     mh_helper( &heardl, &mhlcount, YES );
  290. }
  291.  
  292. VOID ccpmh3()
  293. {
  294.     mh_helper( &l3heardl, &l3mhlcnt, NO );
  295. }
  296.  
  297. VOID mh_helper( list, count, isl2list )
  298. MHEARD *list;
  299. unsigned char *count;
  300. BOOLEAN isl2list;
  301. {
  302.     register mhtyp     *bufpoi;        /* Buffer fuer Meldung         */
  303.     register MHEARD *mhp;
  304.     register unsigned i;
  305.     unsigned mins;
  306.     signed dB;
  307.  
  308.     if( clicnt && issyso() )
  309.     {
  310.         i = nextnumber();    /* neuen Wert holen         */
  311.         if( i <= MAXHEARDLIST )
  312.             *count = i;
  313.     }
  314.     else if( *count )
  315.     {
  316.         bufpoi = putals("\015Callsign    Pkts   Port  Time      ");
  317.         if( isl2list )
  318.         {
  319. #ifdef METERS
  320.             if( meterflags & DEVMETER_ENABLE )
  321.                 putstr( "Dev.   ", bufpoi );
  322.             if( meterflags & SMETER_ENABLE )
  323.                 putstr( meterflags & SMETER_AS_S ? "Sig. " : "dBm  ", bufpoi );
  324. #endif
  325.             putstr( " Type", bufpoi);
  326.         }
  327.         mhp = (MHEARD *)list->prevhb;
  328.         while( mhp != (MHEARD *)list )
  329.         {
  330.             putchr('\015', bufpoi );
  331.             bufpoi->l4time = bufpoi->putcnt;
  332.             putid( mhp->call, bufpoi );
  333.             putspa( 12, bufpoi );
  334.             putnum( mhp->packets, bufpoi );
  335.             putspa( 19, bufpoi );
  336.             putnum( mhp->port, bufpoi );
  337.             putspa( 25, bufpoi );
  338.             i = seconds-mhp->lastheard;
  339.             mins = i / 60;
  340.             putnum( mins / 60, bufpoi );
  341.             putchr(':', bufpoi );
  342.             putnum( mins % 60, bufpoi );
  343.             putchr(':', bufpoi );
  344.             putnum( i % 60, bufpoi );
  345.             putspa( 35, bufpoi );
  346.             if( isl2list )
  347.             {
  348. #ifdef METERS
  349.                 if( meterflags & DEVMETER_ENABLE )
  350.                 {
  351.                     if( mhp->port == 0 )
  352.                     {
  353.                         i = ( mhp->dev * rxdev ) / 100;
  354.                         if( mhp->dev > 254 )
  355.                             putchr( '>', bufpoi );
  356.                         putnum( i/10, bufpoi );
  357.                         putchr( '.', bufpoi );
  358.                         putnum( i % 10, bufpoi );
  359.                     }
  360.                     putspa( 42, bufpoi );
  361.                 }
  362.                 if( meterflags & SMETER_ENABLE )
  363.                 {
  364.                     if( mhp->port == 0 )
  365.                     {
  366.                         i = mhp->sig_level > rxsigmin ? 
  367.                             mhp->sig_level - rxsigmin : 0;
  368.                         if( meterflags & SMETER_AS_S )
  369.                         {
  370.                             i = ( i * rxsmeter ) >> 8;
  371.                             putchr( 'S', bufpoi );
  372.                             putnum( i > 9 ? 9 : i , bufpoi );
  373.                             if( i > 9 )
  374.                                 putchr( '+', bufpoi );
  375.                         }
  376.                         else
  377.                         {
  378.                             dB = (signed)( ( i * rxdb ) >> 8 ) - dbfloor;
  379.                             if( dB < 0 )
  380.                                 putchr( '-', bufpoi );
  381.                             putnum( dB < 0 ? 0-dB : dB, bufpoi );
  382.                         }
  383.                     }
  384.                     putspa( meterflags & 1 ? 47 : 42, bufpoi );
  385.                 }
  386. #endif
  387.                 if( mhp->isnode )
  388.                     putstr( " Node", bufpoi );
  389.                 if( mhp->istcpip )
  390.                     putstr( " TCP/IP", bufpoi );
  391.                 if( mhp->istexnet )
  392.                     putstr( " TexNet", bufpoi );
  393.             }
  394.             else
  395.                 putid( mhp->l3dest, bufpoi );
  396.             mhp = mhp->prevhb;
  397.         }
  398.         seteom( bufpoi );
  399.     }
  400.     else
  401.         putmsg( "MHEARD not running.");
  402. }
  403.  
  404. #else /* L3MONITOR */
  405.  
  406. VOID ccpmh()
  407. {
  408.     register mhtyp     *bufpoi;        /* Buffer fuer Meldung         */
  409.     register MHEARD *mhp;
  410.     register unsigned i;
  411.     unsigned mins;
  412.     signed dB;
  413.  
  414.     if( clicnt && issyso() )
  415.     {
  416.         i = nextnumber();    /* neuen Wert holen         */
  417.         if( i <= MAXHEARDLIST )
  418.             mhlcount = i;
  419.     }
  420.     else if( mhlcount )
  421.     {
  422.         bufpoi = putals("\015Callsign    Pkts   Port  Time      ");
  423. #ifdef METERS
  424.         if( meterflags & DEVMETER_ENABLE )
  425.             putstr( "Dev.   ", bufpoi );
  426.         if( meterflags & SMETER_ENABLE )
  427.             putstr( meterflags & SMETER_AS_S ? "Sig. " : "dBm  ", bufpoi );
  428. #endif
  429.         putstr( " Type\015", bufpoi);
  430.         mhp = (MHEARD *)heardl.lprev;
  431.         while( mhp != (MHEARD *)&heardl )
  432.         {
  433.             bufpoi->l4time = bufpoi->putcnt;
  434.             putid( mhp->call, bufpoi );
  435.             putspa( 12, bufpoi );
  436.             putnum( mhp->packets, bufpoi );
  437.             putspa( 19, bufpoi );
  438.             putnum( mhp->port, bufpoi );
  439.             putspa( 25, bufpoi );
  440.             i = seconds-mhp->lastheard;
  441.             mins = i / 60;
  442.             putnum( mins / 60, bufpoi );
  443.             putchr(':', bufpoi );
  444.             putnum( mins % 60, bufpoi );
  445.             putchr(':', bufpoi );
  446.             putnum( i % 60, bufpoi );
  447.             putspa( 35, bufpoi );
  448. #ifdef METERS
  449.             if( meterflags & DEVMETER_ENABLE )
  450.             {
  451.                 if( mhp->port == 0 )
  452.                 {
  453.                     i = ( mhp->dev * rxdev ) / 100;
  454.                     if( mhp->dev > 254 )
  455.                         putchr( '>', bufpoi );
  456.                     putnum( i/10, bufpoi );
  457.                     putchr( '.', bufpoi );
  458.                     putnum( i % 10, bufpoi );
  459.                 }
  460.                 putspa( 42, bufpoi );
  461.             }
  462.             if( meterflags & SMETER_ENABLE )
  463.             {
  464.                 if( mhp->port == 0 )
  465.                 {
  466.                     i = mhp->sig_level > rxsigmin ? 
  467.                         mhp->sig_level - rxsigmin : 0;
  468.                     if( meterflags & SMETER_AS_S )
  469.                     {
  470.                         i = ( i * rxsmeter ) >> 8;
  471.                         putchr( 'S', bufpoi );
  472.                         putnum( i > 9 ? 9 : i , bufpoi );
  473.                         if( i > 9 )
  474.                             putchr( '+', bufpoi );
  475.                     }
  476.                     else
  477.                     {
  478.                         dB = (signed)( ( i * rxdb ) >> 8 ) - dbfloor;
  479.                         if( dB < 0 )
  480.                             putchr( '-', bufpoi );
  481.                         putnum( dB < 0 ? 0-dB : dB, bufpoi );
  482.                     }
  483.                 }
  484.                 putspa( meterflags & 1 ? 47 : 42, bufpoi );
  485.             }
  486. #endif
  487.             if( mhp->isnode )
  488.                 putstr( " Node", bufpoi );
  489.             if( mhp->istcpip )
  490.                 putstr( " TCP/IP", bufpoi );
  491.             if( mhp->istexnet )
  492.                 putstr( " TexNet", bufpoi );
  493.             putchr('\015', bufpoi );
  494.             mhp = mhp->prevhb;
  495.         }
  496.         seteom( bufpoi );
  497.     }
  498.     else
  499.         putmsg( "MHEARD not running.");
  500. }
  501.  
  502. #endif /* L3MONITOR */
  503.  
  504. #endif
  505.  
  506. /*---------------------------------------------------------------------------*/
  507. #ifdef TALKCMD
  508.  
  509. /* TALK command. Firstly, send a message to all stations currently in the
  510.  * conference informing them that a new station has joined them. Then set
  511.  * the status to 4 so that the user is in the conference. Then, if the
  512.  * user had put text after the talk command, send that text to all users
  513.  * who are not in the conference but are connected idle to the switch.
  514.  * Finally, send a message to the user telling him he is in the conference.
  515.  */
  516.  
  517. VOID ccpcht()
  518. {
  519.     notify( myid, 4, this_station(), NULL, " has joined you.", 16 );
  520.     userpo->status = 4;
  521.     if( clicnt > 0 )
  522.         notify( this_station(), 1, NULL, NULL, clipoi, clicnt );
  523.     putmsg("Talk mode. Type '/ex' to leave.");
  524. }
  525.  
  526. /* helper to the above - return a pointer to the callsign of this user
  527.  */
  528. char *this_station()
  529. {
  530.     return( calofs( 'U', userpo->cblk_u, userpo->typ_u ) ); 
  531. }
  532.  
  533. /* helper utility to TALK command. sends a message from 'sender' to all
  534.  * level 7 switch users whose current status matches that given. The
  535.  * message consists of an optional callsign followed by the message text
  536.  * Also, do not send the msg to the user who sent it ( ie userpo-> )
  537.  *
  538.  * The optionalcalls are either callsigns or numeric values
  539.  * depending on the setting of the top 2 bits of status.
  540.  */
  541.  
  542. VOID notify( sender, status, optionalcall1, optionalcall2, msg, msglength )
  543. char *sender;
  544. int status, msglength;
  545. char *optionalcall1, *optionalcall2;
  546. char *msg;
  547. {
  548.     register mhtyp *bufpoi;
  549.     register usrtyp *usrptr;
  550.     register int i;
  551.     char *ptr;
  552.  
  553.     for( usrptr = (usrtyp *)usccpl.lnext;        /* loop thru all ccp */
  554.          (usrtyp *)&usccpl != usrptr;        /* users             */
  555.          usrptr = usrptr->unext )
  556.     {
  557.         if( (usrptr->status == (status & 0x3f)) && (usrptr != userpo) && nmbfre >= 200)
  558.         {
  559.             bufpoi = (mhtyp *)allocb();
  560.             bufpoi->l2lnk = usrptr->cblk_u;
  561.             bufpoi->usrtyp = usrptr->typ_u;
  562.             putid( sender, bufpoi );
  563.             putstr( ">> ", bufpoi );
  564.             if( status & 0x80 )
  565.                 putnum_and_space( optionalcall1, bufpoi );
  566.             else if( optionalcall1 != NULL )
  567.                 putid_and_space( optionalcall1, bufpoi );
  568.             if( status & 0x40 )
  569.                 putnum_and_space( optionalcall2, bufpoi );
  570.             else if( optionalcall2 != NULL )
  571.                 putid_and_space( optionalcall2, bufpoi );
  572.             i = msglength;
  573.             ptr = msg;
  574.             while( i-- > 0 )
  575.                 putchr( *ptr++, bufpoi );
  576.             seteom( bufpoi );
  577.         }
  578.     }
  579. }
  580.  
  581. #endif
  582.  
  583. /*---------------------------------------------------------------------------*/
  584. #ifdef LINKSCMD
  585.  
  586. VOID ccplin()
  587. {
  588.     register mhtyp *bufpoi;
  589.     register unsigned i;
  590.     register l2ltyp *link;
  591.  
  592.     bufpoi = putals( "Links:" );
  593.     for( i = MAXL2L, link = lnktbl; i != 0 ; i--, link++ )
  594.     {
  595.         if( link->state != 0 )        /* L2SDSCES */
  596.         {
  597.             putchr( '\015', bufpoi );
  598.             putid_and_space( link->srcid, bufpoi );
  599.             putid_and_space( link->dstid, bufpoi );
  600.             putdil( link->viaid, bufpoi );
  601.             putchr( ' ', bufpoi );
  602.             putnum_and_space( link->state, bufpoi );
  603.             putnum_and_space( link->liport, bufpoi );
  604.             putnum_and_space( link->tries, bufpoi );
  605.         }
  606.     }
  607.     seteom( bufpoi );
  608. }
  609. #endif
  610.  
  611. /*---------------------------------------------------------------------------*/
  612. #ifdef MANAGED
  613.  
  614. char L7id[] = "L7    `";
  615.  
  616. /* The manager command does the same as sysop, but sets state to 5 so that
  617.  * the command interpreter will set it to 6 if successful.
  618.  */
  619.  
  620. VOID ccpman()
  621. {
  622.     ccpsys();
  623.     userpo->status = 5;
  624. }
  625.  
  626. #ifdef CLOSEDOWN
  627. /*---------------------------------------------------------------------------*/
  628. /*  The closedown command shuts down the node if executed properly.
  629.  * If not, you forfit sysop status
  630.  */
  631. VOID ccpclo()
  632. {
  633.     if( issyso() && ( upcase( *clipoi ) == 'A' ) )
  634.     {
  635.         ccpsys();
  636.         userpo->status = 7;
  637.         userpo->sysflg = 0;
  638.     }
  639. }
  640. #endif
  641.  
  642. #ifdef MODIFIED
  643. /*---------------------------------------------------------------------------*/
  644. /* The help command prints out an interesting message
  645. */
  646. VOID ccphlp()
  647. {
  648.     putmsg( helpmsg );
  649. }
  650.  
  651. /*---------------------------------------------------------------------------*/
  652. /* The beacon text command sets an optional string on the beacon packet
  653. */
  654. VOID ccpbtx()
  655. {
  656.     settxt( beatxt, 79 );
  657.     putmsg( beatxt );
  658. }
  659.  
  660. /*---------------------------------------------------------------------------*/
  661. /* The connect-text command sets an optional string on connect
  662. */
  663. VOID ccpctx()
  664. {
  665.     settxt( contxt, 79 );
  666.     putmsg( contxt );
  667. }
  668.  
  669. VOID settxt( string, length )
  670. register char *string;
  671. register unsigned length;
  672. {
  673.     register unsigned chaptr;
  674.  
  675.     if( issyso() )
  676.     {
  677.         chaptr = 0;
  678.         if( *clipoi != '*' )
  679.         {
  680.             while( string[chaptr] )
  681.                 chaptr++;
  682.             while( clicnt != 0 && chaptr < length )
  683.             {
  684.                 string[chaptr++] = *clipoi;
  685.                 nxtcli();
  686.             }
  687.             if( chaptr < length )
  688.                 string[chaptr++] = '\r';
  689.         }
  690.         string[chaptr] = '\0';
  691.     }
  692. }
  693. #endif
  694.  
  695. #endif        
  696.  
  697. /*---------------------------------------------------------------------------*/
  698. #ifdef CWID
  699. /* Calibrate command. Only works for the sysop. 
  700.  */
  701. VOID ccpcal()
  702. {
  703.     if( !issyso() )                /* check if sysop           */
  704.         return;
  705.     calper = nextnumber();    /* get desired period       */
  706.     if( calper < 1 || calper > 60 )        /* only do it if 1 -> 60 sec*/
  707.         return;
  708.     caltog = nextnumber();    /* get optional toggle per. */
  709.     if( caltog < 1 || caltog > calper )    /* force to be  1 -> calper */
  710.         caltog = calper+1;
  711. #ifndef MSDOS
  712.     if( cwstate == 3 )    /* only do it if not doing cwid at moment   */
  713.     {
  714.         cwstate = -2;        /* set state to -2 to indicate cal  */
  715.         kicktx( HDLCPORT );    /* and go for it !                  */
  716.     }
  717.     else
  718. #endif
  719.         putmsg("Busy.");
  720. }
  721. #endif
  722.  
  723. /*---------------------------------------------------------------------------*/
  724. #ifdef MODIFIED
  725. /* this function is used by ccpbbs etc to give a friendly message to the user
  726.  */
  727. VOID con_try_msg( callsign )
  728. char *callsign;
  729. {
  730.     register mhtyp *bufpoi;
  731.  
  732.     if( hlpflg & 1 )
  733.     {
  734.         bufpoi = putals("Please wait, trying ");
  735.         putstr( callsign, bufpoi );
  736.         seteom( bufpoi );
  737.     }
  738. }
  739. #endif
  740.  
  741. /*---------------------------------------------------------------------------*/
  742. #ifdef MODIFIED
  743. /* This command is used to send an arbitrary UI frame from the switch
  744.  * The syntax is :
  745.  *    UI dest text_that_is_to_be_sent
  746.  */
  747. VOID ccpui()
  748. {
  749.     char call[7];
  750.     register mhtyp *bufpoi;
  751.  
  752.     if( !skipspace() || !getcal( &clicnt, &clipoi, 0, call))
  753.         return;
  754.     (bufpoi = (mhtyp *)allocb())->pid = PID_NO_L3;
  755.     while( clicnt  /* > 0 */ )
  756.     {
  757.         putchr( *clipoi, bufpoi );
  758.         nxtcli();
  759.     }
  760.     putchr( '\015', bufpoi );
  761.     rwndmb( bufpoi );
  762.     sdui( beadil, call, this_station(), HDLCPORT, bufpoi );
  763.     dealmb( bufpoi );    
  764. }
  765. #endif
  766.  
  767. /*---------------------------------------------------------------------------*/
  768. #ifdef ACL
  769.  
  770. /* ACL command interface routine.
  771.  * ACL with no parameters ( or if not sysop ) prints the ACL
  772.  * If a parameter is given, it must be of one of the following syntax types
  773.  *       ACL  callsign   +   value
  774.  *       ACL  callsign   -
  775.  *       ACL  *   value
  776.  *
  777.  * The first makes an entry, the second deletes one, the last sets the default
  778.  */
  779. VOID ccpacl()
  780. {
  781.     register mhtyp *bufpoi;
  782.     register unsigned i;
  783.     register ACLMB *aclp;
  784.     char callsign[7];
  785.  
  786.     if( !issyso() )
  787.     {
  788.         i = 0;
  789.         aclp = acl.prevaclb;
  790.         bufpoi = putals("ACL: Default ");
  791.         putnum( acl_default, bufpoi );
  792.         putstr( ", Mask ", bufpoi );
  793.         putnum( acl_mask, bufpoi );
  794.         while( aclp != &acl )
  795.         {
  796.             if( aclp->entry[i].call[0] != '\0' )
  797.             {
  798.                 putchr( '\r', bufpoi );
  799.                 bufpoi->l4time = bufpoi->putcnt;
  800.                 putid( aclp->entry[i].call, bufpoi );
  801.                 putspa( 10, bufpoi );
  802.                 putnum( aclp->entry[i].value, bufpoi );
  803.             }
  804.             if( ++i >= 4 )
  805.             {
  806.                 i = 0;
  807.                 aclp = aclp->prevaclb;
  808.             }
  809.         }
  810.         seteom( bufpoi );
  811.     }
  812.     else if( *clipoi == '*' )
  813.     {
  814.         nxtcli();
  815.         acl_default = nextnumber();
  816.     }
  817.     else if( *clipoi == '&' )
  818.     {
  819.         nxtcli();
  820.         acl_mask = nextnumber();
  821.     }
  822.     else if( !getcal( &clicnt, &clipoi, 0, callsign ) )
  823.         invcal();
  824.     else if( *clipoi == '-' )
  825.     {
  826.         if( !acl_delete( callsign ) )
  827.             putmsg("Error in deleting entry");
  828.     }
  829.     else if( *clipoi == '+' )
  830.     {
  831.         nxtcli();
  832.         if( ! skipspace() )
  833.             putmsg("You must give a value!");
  834.         else if( !acl_add( callsign, nextnumber() ) )
  835.             putmsg("Error in adding value");
  836.     }
  837.     else
  838.         putmsg("Syntax error");
  839. }
  840.  
  841. /* This function, called by ccpacl() adds or updates an entry in the list
  842.  *
  843.  * It returns TRUE  if it succeeds
  844.  *            FALSE if it fails ( ie not enough RAM )
  845.  */
  846. acl_add( call, value )
  847. register char *call;
  848. unsigned value;
  849. {
  850.     /* check if there is already an entry for this call
  851.      */
  852.     if( !acl_find( call, 1 ) )
  853.     {
  854.         /* If not, create or find space for a new entry
  855.          * and then copy the callsign in. acl_free() will
  856.          * return FALSE if there is not enough space.
  857.          */
  858.         if( acl_free() )
  859.             cpyid( aclentry->call, call );
  860.         else
  861.             return( FALSE );
  862.     }
  863.  
  864.     /* now copy the acl value into the entry
  865.      */
  866.     aclentry->value = value;
  867.     return( TRUE );
  868. }
  869.  
  870. /* This function, called by ccpacl() is used to delete an entry
  871.  *
  872.  * It returns TRUE  on success
  873.  *            FALSE on failure ( ie no match found for callsign )
  874.  */
  875. acl_delete( call )
  876. char *call;
  877. {
  878.     register int i;
  879.  
  880.     /* give up if no entry found for callsign
  881.      */
  882.     if( !acl_find( call, 1 ) )
  883.         return( FALSE );
  884.  
  885.     /* delete the entry by setting first char of callsign to null
  886.      */
  887.     aclentry->call[0] = '\0';
  888.  
  889.     /* now count the number of deleted entries in this buffer
  890.      * If all 4 are now unused, free up the buffer
  891.      */
  892.     for( i=0; i<4 && aclcur->entry[i].call[0] == '\0'; i++ )
  893.         ;
  894.     if( i == 4 )
  895.         dealoc( unlink( aclcur ) );
  896.     return( TRUE );
  897. }
  898.  
  899. /* This function finds the first free space to store an ACL entry,
  900.  * either as the first hole found or as the first entry in a new buffer
  901.  */
  902. acl_free()
  903. {
  904.     register ACLMB *aclp;
  905.     register int i;
  906.  
  907.     i = 0;
  908.     aclp = acl.prevaclb;
  909.     while( aclp != &acl )
  910.     {
  911.         /* if the entry is free, point to it and return TRUE
  912.          */
  913.         if( aclp->entry[i].call[0] == '\0' )
  914.         {
  915.             aclentry = &aclp->entry[i];
  916.             aclcur = aclp;
  917.             return( TRUE );
  918.         }
  919.  
  920.         /* otherwise, step on to next entry, or next buffer if
  921.          * all 4 have been checked
  922.          */
  923.         if( ++i >= 4 )
  924.         {
  925.             i = 0;
  926.             aclp = aclp->prevaclb;
  927.         }
  928.     }
  929.  
  930.     /* no entry is unused, so if there is lots of space,
  931.      * allocate a new buffer
  932.      */
  933.     if( nmbfre < 200 )
  934.     {
  935.         aclentry = aclcur = NULL;
  936.         return( FALSE );
  937.     }
  938.  
  939.     /* now point to it, and mark all its entries as unused
  940.      * then link it into the linked list
  941.      */
  942.     aclcur = aclp = allocb();
  943.     for( i = 0; i < 4; i++ )
  944.         aclp->entry[i].call[0] = '\0';
  945.     relink( aclp, acl.nextaclb );
  946.     aclentry = &aclp->entry[0];
  947.     return( TRUE );
  948. }
  949.  
  950. /* This routine looks for an entry that matches call[].
  951.  * If type is TRUE, it must also match SSID, otherwise SSID is ignored
  952.  */
  953. acl_find( call, type )
  954. register char *call;
  955. {
  956.     register ACLMB *aclp;
  957.     register int i;
  958.  
  959.     i = 0;
  960.     aclp = acl.prevaclb;
  961.     while( aclp != &acl )
  962.     {
  963.         /* try to match either using or without SSID
  964.          * If match found, point to it & return 
  965.          */
  966.         if(( type && cmpid( call, aclp->entry[i].call ))
  967.           ||
  968.           ( !type && cmpcal( call, aclp->entry[i].call )))
  969.         {
  970.             aclentry = &aclp->entry[i];
  971.             aclcur = aclp;
  972.             return( TRUE );
  973.         }
  974.         
  975.         /* step on thru 4 entries per buffer, then all buffers
  976.          */
  977.         if( ++i >= 4 )
  978.         {
  979.             i = 0;
  980.             aclp = aclp->prevaclb;
  981.         }
  982.     }
  983.     
  984.     /* failed to find match - clear pointers and return FALSE
  985.      */
  986.     aclentry = aclcur = NULL;
  987.     return( FALSE );
  988. }
  989.  
  990. /* THIS IS THE MAIN ACL INTERFACE ROUTINE FOR THE SWITCH FUNCTIONS
  991.  * Given a callsign, it returns an ACL value for that callsign,
  992.  * as either the value stored against that callsign with SSID match
  993.  * or as the first matching entry ignoring SSID where that entry has
  994.  * the IGNORE_SSID bit set
  995.  */
  996. acl_entry( callsign )
  997. register char *callsign;
  998. {
  999.     if( acl_find( callsign, 1 ) )
  1000.         return( aclentry->value );
  1001.     else if( acl_find( callsign, 0 ) && ( aclentry->value & ACL_IGNORE_SSID ))
  1002.         return( aclentry->value );
  1003.     return( acl_default );
  1004. }
  1005.  
  1006. #endif
  1007.  
  1008. /*---------------------------------------------------------------------------*/
  1009. #ifdef METERS
  1010. VOID ccpadc()
  1011. {
  1012.     register mhtyp *bufpoi;
  1013.     
  1014.     bufpoi = putals("\r");
  1015.     if( meterflags & CH3_ENABLE )
  1016.         adc_show( CH3_START, adcmult1, adcofs1, CH3_DIV1000, 
  1017.                   CH3_DECIMALS, units1, bufpoi );
  1018.     if( meterflags & CH4_ENABLE )
  1019.         adc_show( CH4_START, adcmult2, adcofs2, CH4_DIV1000, 
  1020.                   CH4_DECIMALS, units2, bufpoi );
  1021. #ifdef ALL_METERS
  1022.     if( meterflags & CH1_ENABLE )
  1023.         adc_show( CH1_START, adcmult3, adcofs3, CH1_DIV1000, 
  1024.                   CH1_DECIMALS, units3, bufpoi );
  1025.     if( meterflags & CH2_ENABLE )
  1026.         adc_show( CH2_START, adcmult4, adcofs4, CH2_DIV1000, 
  1027.                   CH2_DECIMALS, units4, bufpoi );
  1028. #endif
  1029.     seteom( bufpoi );
  1030. }
  1031.  
  1032. adc_show( channel, multiplier, offset, div_1000, decimals, units, bufpoi )
  1033. register mhtyp *bufpoi;
  1034. signed multiplier, offset;
  1035. unsigned channel, div_1000, decimals;
  1036. char *units;
  1037. {
  1038.     register signed i;
  1039.  
  1040.     i = ( (signed) adc_read( channel ) - offset ) * multiplier;
  1041.     if( i < 0 )
  1042.     {
  1043.         putchr( '-', bufpoi );
  1044.         i = - i;
  1045.     }
  1046.     i /= ( meterflags & div_1000 ) ? 100 : 10;
  1047.     putnum( i / 10, bufpoi );
  1048.     if( meterflags & decimals )
  1049.     {
  1050.         putchr( '.', bufpoi );
  1051.         putnum( i % 10, bufpoi );
  1052.     }
  1053.     putchr( ' ', bufpoi );
  1054.     putstr( units , bufpoi );
  1055. }
  1056.  
  1057. #ifdef PORTABLE
  1058.  
  1059. adc_read( channel )
  1060. {
  1061.     return( random() & 0xff );
  1062. }
  1063.  
  1064. #else
  1065. #asm
  1066.     .z80
  1067.     public adc_read_
  1068.  
  1069. ADC    equ    32
  1070.     extrn    DIinc_, decEI_
  1071.  
  1072. adc_read_:    pop    hl
  1073.     pop        de
  1074.     push    de
  1075.     push    hl
  1076.     call     DIinc_
  1077.     ld    a,e
  1078.     out    (ADC),A
  1079.     ld    a,31
  1080. adcr1:    dec    a
  1081.     jr    nz, adcr1
  1082.     in    a,(ADC)
  1083.     call    decEI_
  1084.     ld    l,a
  1085.     ld    h,0
  1086.     or    a
  1087.     ret
  1088.     
  1089.     .8080
  1090. #endasm
  1091. #endif
  1092.  
  1093. /*---------------------------------------------------------------------------*/
  1094. /* The adc channel 1 text command sets an optional string for adc units
  1095. */
  1096. VOID ccpad1()
  1097. {
  1098.     ccp_adcx( units1 );
  1099. }
  1100.  
  1101. /*---------------------------------------------------------------------------*/
  1102. /* The adc channel 2 text command sets an optional string for adc units
  1103. */
  1104. VOID ccpad2()
  1105. {
  1106.     ccp_adcx( units2 );
  1107. }
  1108.  
  1109. #ifdef ALL_METERS
  1110. /*---------------------------------------------------------------------------*/
  1111. /* The adc channel 3 text command sets an optional string for adc units
  1112. */
  1113. VOID ccpad3()
  1114. {
  1115.     ccp_adcx( units3 );
  1116. }
  1117.  
  1118. /*---------------------------------------------------------------------------*/
  1119. /* The adc channel 4 text command sets an optional string for adc units
  1120. */
  1121. VOID ccpad4()
  1122. {
  1123.     ccp_adcx( units4 );
  1124. }
  1125. #endif /* ALL_METERS */
  1126.  
  1127. VOID ccp_adcx( string )
  1128. register char *string;
  1129. {
  1130.     settxt( string, 12 );
  1131.     putmsg( string );
  1132. }
  1133.  
  1134.  
  1135. #endif
  1136.  
  1137.  
  1138. /*--- Ende Level7B ----------------------------------------------------------*/
  1139.